﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Threading;
using System.Collections;

namespace B1103492
{
    /// <summary>
    /// 本类相对来说是最复杂的一个类
    /// 
    /// 本类的目的是封装原来3rd party codes的fishplane
    /// 本类不是一个独立的窗口，只是一个子窗口，
    /// 所以后缀名是 SubWindow，只能作为控件添加到其他窗口。
    /// </summary>
    public partial class FishPhotosShowSubWindow : UserControl
    {
        #region 变量组
        // fishPhotos用于保存读取到的图片数据对象
        List<FishEyePanel>fishPhotos = new List<FishEyePanel>();

        // addPerson 是窗口对象传递的本地副本，便于
        // 窗口对象进行操作。
        AddPersonPhotoWindow addPerson;
        #endregion

        #region 子窗口的初始化，与公共函数部分
        public FishPhotosShowSubWindow()
        {
            InitializeComponent();
            fishPhotos.Clear();
        }

        private void FishPhotosAddInGrid()
        {
            int i = 0;
            // 下面程序可以有可以没有，就不列入程序了。
            // Photos.ColumnDefinitions.Add(new ColumnDefinition());
            foreach (var fishPhoto in fishPhotos)
            {
                // grid定义行 并设置行相同的宽度，如下：
                // RowDefinition rd = new RowDefinition();
                // rd.Height = new GridLength(1, GridUnitType.Star);
                // 本程序中，调试后发现效果不是很好，就不采用了。
                Photos.RowDefinitions.Add(new RowDefinition());

                Grid.SetColumn(fishPhoto, 0);
                Grid.SetRow(fishPhoto, i++);
                Photos.Children.Add(fishPhoto);
            }
        }
        #endregion

        #region 随着鼠标移动时的语音提醒

        /// <summary>
        /// 参考代码：http://msdn.microsoft.com/en-us/library/system.threading.thread.aspx
        /// 线程部分的程序,做了修改.
        /// 用到上面的变量 static senderName来传递发送者的名字。
        /// </summary>
        /// <param name="sender"> as Image</param>
        /// <param name="e"></param>
        void myImage_ToolTipOpening(object sender, ToolTipEventArgs e)
        {
            TextToSpeech.stopRead();
            TextToSpeech.readString((sender as Image).ToolTip.ToString().Split(new char[] { '.' })[0]);
        }
        #endregion

        #region 用于显示主窗口和查询窗口的部分
        public FishPhotosShowSubWindow(Hashtable t):this()
        {
            try
            {

                FishPhotosGetImageFromPersonInfor(t);
                FishPhotosAddInGrid();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void myImageShowPersonInfor_MouseDown
            (object sender, MouseButtonEventArgs e)
        {
            // 没有找到合适的函数直接写sender对象的名字，就用了下面这种复杂的方式完成了。
            // 后面+9的原因是，(sender as Image).Source.ToString()把file:///与/都删除。
            // 这是复杂的方式：
            // string senderName = (sender as Image).Source.ToString().Substring(photoPath.Length+9);
            // 后来通过Tooltip传递姓名，就可以简化如下了。
            // 最后.Split(new char[]{'.'})[0];把ToolTip用'.'分开，只保留第0个子字符串。
            PersonInformationWindow person =
                new PersonInformationWindow(LowestData.LinqSelectString()[(sender as Image).ToolTip.ToString()] as Informations); 
            person.ShowInTaskbar = false;
            //
            //WindowStartupLocation，该参数使用不怎么方便，就放弃使用该函数。
            // 参考文章：
            // http://www.cnblogs.com/daocaoren/archive/2011/06/18/2084037.html
            // http://zhidao.baidu.com/question/35443958
            // http://msdn.microsoft.com/en-us/library/system.windows.forms.control.mouseposition.aspx
            // http://msdn.microsoft.com/en-us/library/system.windows.input.mouseeventargs.getposition.aspx

            Point p = e.GetPosition(this);
            double X = p.X;
            double Y = p.Y;
            if (X > SystemParameters.PrimaryScreenWidth - person.Width)
            {
                X -= person.Width;
            }
            if (Y > SystemParameters.PrimaryScreenHeight - person.Height)
            {
                Y -= person.Height;
            }
            person.Left = X;
            person.Top = Y;
            
            person.Show();
        }

        private void FishPhotosGetImageFromPersonInfor
            (Hashtable persons)
        {
            if (persons.Count == 0)
                return;

            // 为了充分利用窗口界面，采用动态分行的方式。
            // 下面数字5的采用是试用了2,4,8之后，认为5较合适。
            int ColumnNumber = (int)Math.Sqrt
                (5 * persons.Count);
            int i = 0;
            foreach (Informations person in persons.Values)
            {

                if (i % ColumnNumber == 0)
                {
                    fishPhotos.Add(new FishEyePanel());
                }
                // 参考程序：help里面的How to: Use the Image Element，有改动。
                Image myImage = new Image();
                myImage.Width = 256;//一定不可以删除，否则错。
                myImage.Source =
                    DealImage.GetBitmapImageFromFile(
                        Environment.CurrentDirectory + "/" + person.photoRelativeName,
                        512);
                myImage.MouseDown += new MouseButtonEventHandler(myImageShowPersonInfor_MouseDown);
                myImage.ToolTip = person.name;
                myImage.ToolTipOpening += new ToolTipEventHandler(myImage_ToolTipOpening);
                fishPhotos[i / ColumnNumber].Children.Add(myImage);
                i++;
            }

            // 下面的程序是避免下层大的图像出现，调试后发现效果良好。
            for (; i % ColumnNumber > 0; i++)
            {
                // 参考程序：上面程序逐步删除不要的部分，调试得到的。
                Image myImage = new Image();
                myImage.Width = 256;//一定不可以删除，否则错。
                fishPhotos[i / ColumnNumber].Children.Add(myImage);
            }
        }
        
        #endregion

        #region 用于显示添加照片窗口的部分
        public FishPhotosShowSubWindow(AddPersonPhotoWindow appw)
            : this()
        {
            addPerson = appw;
            try
            {
                var imgs = SelectImages();
                FishPhotosGetImageFromFile(imgs);
                FishPhotosAddInGrid();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        // 只能打开特定相对路径"Information/Photo"的照片。
        private static IEnumerable<FileInfo> SelectImages()
        {
            string photoPath = "Information/Photo";

            FileInfo[] Files = new DirectoryInfo(photoPath).GetFiles();
            var imgs = (from fi in Files select fi);
            return imgs;
        }

        private void FishPhotosGetImageFromFile
            (IEnumerable<FileInfo> imgs)
        {
            if (imgs.Count<FileInfo>() == 0)
            {
                MessageBox.Show("Information/Photo",
                    "出错了！",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
                addPerson.Close();
                return;
            }
            // 为了充分利用窗口界面，采用动态分行的方式。
            // 数字5的选择，见上面的说明。
            int ColumnNumber = (int)Math.Sqrt(5 * imgs.Count<FileInfo>());
            int i = 0;
            foreach (var filename in imgs)
            {

                if (i % ColumnNumber == 0)
                {
                    fishPhotos.Add(new FishEyePanel());
                }

                // 参考程序：help里面的How to: Use the Image Element，有改动。
                Image myImage = new Image();
                myImage.Width = 64;//一定不可以删除，否则错。
                myImage.Source =
                    DealImage.GetBitmapImageFromFile(
                        filename.FullName,
                        128);
                myImage.MouseDown += 
                    new MouseButtonEventHandler
                        (addPerson.chooseImageAndClose_MouseDown);
                myImage.ToolTip = filename.Name;
                myImage.ToolTipOpening += new ToolTipEventHandler(myImage_ToolTipOpening);
                fishPhotos[i / ColumnNumber].Children.Add(myImage);
                i++;
            }
            // 下面的程序是避免下层大的图像出现，调试后发现效果良好。
            for (; i % ColumnNumber > 0;i++ )
            {
                // 参考程序：上面程序逐步删除不要的部分，调试得到的。
                Image myImage = new Image();
                myImage.Width = 64;//一定不可以删除，否则错。
                fishPhotos[i / ColumnNumber].Children.Add(myImage);
            }
        }

        #endregion
    }
}
